﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using UricaoWeb.Datos.ConexionBD.Propiedad;
using UricaoWeb.Datos.Excepciones.Propiedad;

namespace UricaoWeb.LogicaDeNegocios.Propiedad
{
    ///<summary>
    /// Clase ControladorPropiedad
    /// Se encarga de recibir y ejecutar las peticiones de la presentación
    /// hacia la capa de datos, creando una instancia de la clase ModeloPropiedad
    /// para agregar, modificar, eliminar y consultar propiedades
    /// además de realizar otras validaciones requeridas por el negocio y la presentación
    ///</summary>
    public class ControladorPropiedad
    {
        #region Atributos

        private ModeloPropiedad _datosPropiedad;

        #endregion

        #region Propiedades

        public ModeloPropiedad DatosPropiedad
        {
            get { return _datosPropiedad; }
            set { _datosPropiedad = value; }
        }

        #endregion Propiedades

        #region Constructor - Métodos

        public ControladorPropiedad()
        {
            _datosPropiedad = new ModeloPropiedad();
        }

        /// <summary>
        /// Función para consultar propiedades de manera parametrizada, 
        /// ya sea por id, por nombre o por hotel al que pertenece
        /// </summary>
        /// <param name="parametro">Tipo de la consulta a realizar</param>
        /// <param name="valorBusqueda">Valor de la consulta a realizar</param>
        /// <returns>
        /// Devuelve una lista de propiedades
        /// </returns>
        public List<ModeloPropiedad> ConsultarPropiedadesConParametros(string parametro, string valorBusqueda)
        {
            List<ModeloPropiedad> propiedades = new List<ModeloPropiedad>();

            try
            {
                propiedades = _datosPropiedad.ConsultarPropiedadesConParametros(parametro, valorBusqueda);
            }
            catch (PropiedadException e)
            { throw e; }
            return propiedades;
        }

        /// <summary>
        /// Función para consultar propiedades de manera parametrizada, 
        /// ya sea por id, por nombre o por hotel al que pertenece
        /// realiza validaciones/modificaciones adicionales en la lista devuelta
        /// para el llenado y posterior visualización correcta de un GridView
        /// </summary>
        /// <param name="parametro">Tipo de la consulta a realizar</param>
        /// <param name="valorBusqueda">Valor de la consulta a realizar</param>
        /// <param name="numElemDeseadosPorPag)">Cantidad de elementos que se quieren mostrar por página del GridView</param>
        /// <returns>
        /// Devuelve una lista de propiedades
        /// </returns>
        public List<ModeloPropiedad> ConsultarPropiedadesConParametrosGrid(string parametro, string valorBusqueda, int numElemDeseadosPorPag)
        {
            List<ModeloPropiedad> propiedades = new List<ModeloPropiedad>();

            try
            {
                propiedades = _datosPropiedad.ConsultarPropiedadesConParametros(parametro, valorBusqueda);
            }
            catch (PropiedadException e)
            { throw e; }

            int numElementosConsulta = propiedades.Count;
            int numPagGrid = numElementosConsulta / numElemDeseadosPorPag;

            if (numElementosConsulta > numElemDeseadosPorPag)
            {
                for (int i = numPagGrid*numElemDeseadosPorPag; i < numElementosConsulta; i++)
                {
                    ModeloPropiedad propiedad = new ModeloPropiedad();
                    propiedades.Add(propiedad);
                }
            }
            return propiedades;
        }

        /// <summary>
        /// Función para consultar una propiedad dado el id de la misma
        /// este método se llama a la hora de modificar
        /// </summary>
        /// <param name="idPropiedad">Id de la propiedad que se quiere consultar para modificar</param>
        /// <returns>
        /// Devuelve una propiedad a modificar
        /// </returns>
        public void ConsultarPropiedadModificar(int idPropiedad)
        {
            ModeloPropiedad propiedad = new ModeloPropiedad();
            List<ModeloPropiedad> propiedades = new List<ModeloPropiedad>();

            try
            {
                propiedades = _datosPropiedad.ConsultarPropiedadesConParametros("id", Convert.ToString(idPropiedad));
            }
            catch (PropiedadException e)
            { throw e; }

            propiedad = propiedades[0];
            this._datosPropiedad = propiedad;
        }

        /// <summary>
        /// Función para agregar una propiedad, recibe todos los datos de una propiedad
        /// </summary>
        /// <param name="fkHotel">Id del hotel </param>
        /// <param name="nombrePropiedad">Nombre de la propiedad</param>
        /// <param name="tipoPropiedad">Tipo de propiedad</param>
        /// <param name="descripcionPropiedad">Descripcion de la propiedad</param>
        /// <param name="ubicacionPropiedad">Ubicación de la propiedad</param>
        /// <param name="imagenPropiedad">Dirección de la imagen de la propiedad</param>
        /// <returns>
        /// Devuelve true si se agrego la propiedad correctamente y false si no
        /// </returns>
        public bool AgregarPropiedad(int fkHotel, string nombrePropiedad, string tipoPropiedad, string descripcionPropiedad, string ubicacionPropiedad, string imagenPropiedad)
        {
            ModeloPropiedad propiedad = new ModeloPropiedad();
            propiedad.FkHotel = fkHotel;
            propiedad.NombrePropiedad = nombrePropiedad;
            propiedad.TipoPropiedad = tipoPropiedad;
            propiedad.DescripcionPropiedad = descripcionPropiedad;
            propiedad.UbicacionPropiedad = ubicacionPropiedad;
            propiedad.ImagenPropiedad = imagenPropiedad;
            bool flagInsert;

            try
            {
                flagInsert = _datosPropiedad.AgregarPropiedad(propiedad);
            }
            catch (PropiedadException e)
            { throw e; }

            return flagInsert;
        }

        /// <summary>
        /// Función para modificar una propiedad, recibe todos los datos de una propiedad
        /// </summary>
        /// <param name="idPropiedad">Id de la propiedad a modificar</param>
        /// <param name="fkHotel">Id del hotel </param>
        /// <param name="nombrePropiedad">Nombre de la propiedad</param>
        /// <param name="tipoPropiedad">Tipo de propiedad</param>
        /// <param name="descripcionPropiedad">Descripcion de la propiedad</param>
        /// <param name="ubicacionPropiedad">Ubicación de la propiedad</param>
        /// <param name="imagenPropiedad">Dirección de la imagen de la propiedad</param>
        /// <returns>
        /// Devuelve true si se modificó la propiedad correctamente y false si no
        /// </returns>
        public bool ModificarPropiedad(int idPropiedad, int fkHotel, string nombrePropiedad, string tipoPropiedad, string descripcionPropiedad, string ubicacionPropiedad, string imagenPropiedad)
        {
            ModeloPropiedad propiedad = new ModeloPropiedad();
            propiedad.IdPropiedad = idPropiedad;
            propiedad.FkHotel = fkHotel;
            propiedad.NombrePropiedad = nombrePropiedad;
            propiedad.TipoPropiedad = tipoPropiedad;
            propiedad.DescripcionPropiedad = descripcionPropiedad;
            propiedad.UbicacionPropiedad = ubicacionPropiedad;
            propiedad.ImagenPropiedad = imagenPropiedad;

            bool flagUpdate;

            try
            {
                flagUpdate = _datosPropiedad.ModificarPropiedad(propiedad);
            }
            catch (PropiedadException e)
            { throw e; }

            return flagUpdate;
        }

        /// <summary>
        /// Función para eliminar una propiedad, recibe el id de la propiedad a eliminar
        /// </summary>
        /// <param name="idPropiedad">Id de la propiedad a eliminar</param>
        /// <returns>
        /// Devuelve true si se eliminó la propiedad correctamente y false si no
        /// </returns>
        public bool EliminarPropiedad(int idPropiedad, int idHotel)
        {
            bool flagDelete = false;
            List<ModeloPropiedad> propiedades = ConsultarPropiedadesConParametros("id", Convert.ToString(idPropiedad));
            ModeloPropiedad propiedad = new ModeloPropiedad();

            try
            {
                propiedades = _datosPropiedad.ConsultarPropiedadesConParametros("id", Convert.ToString(idPropiedad));
            }
            catch (PropiedadException e)
            { throw e; }

            propiedad = propiedades[0];

            if (propiedad.FkHotel == idHotel)
            {
                try
                {
                    flagDelete = _datosPropiedad.EliminarPropiedad(idPropiedad);
                }
                catch (PropiedadException e)
                { throw e; }
            }

            return flagDelete;
        }

        /// <summary>
        /// Función que devuelve los distintos tipos de propiedad
        /// </summary>
        /// <returns>
        /// Devuelve una lista de los distintos tipos de propiedad
        /// </returns>
        public List<string> ListarTiposPropiedad()
        {
            return _datosPropiedad.ConsultarTipoPropiedad();
        }

        /// <summary>
        /// Función que devuelve hoteles que son dueños de las distintas propiedades
        /// </summary>
        /// <returns>
        /// Devuelve una lista de los distintos hoteles
        /// </returns>
        public List<Hotel> ListarPropiedadesHoteles()
        {
            List<Hotel> propiedades = new List<Hotel>();

            try
            {
                propiedades = _datosPropiedad.ConsultarPropiedadesHoteles("hoteles");
            }
            catch (PropiedadException e)
            { throw e; }

            return propiedades;
        }

        /// <summary>
        /// Función que verifica la extensión de las imágenes que sube el usuario
        /// </summary>
        /// <param name="nombreArchivo">Nombre del archivo que esta subiendo el usuario</param>
        /// <returns>
        /// Devuelve una lista de los distintos hoteles
        /// </returns>
        public bool VerificarTipoImagen(string nombreArchivo)
        {
            string extension = Path.GetExtension(nombreArchivo);
            switch (extension.ToLower())
            {
                case ".gif":
                    return true;
                case ".png":
                    return true;
                case ".jpg":
                    return true;
                case ".jpeg":
                    return true;
                default:
                    return false;
            }
        }

        /// <summary>
        /// Función para verificar cantidad de caracteres de un textbox
        /// </summary>
        /// <param name="longMin">Cantidad mínima de caracteres deseada</param>
        /// <param name="longMax">Cantidad máxima de caracteres deseada</param>
        /// <param name="longReal">Cantidad de caracteres actual que tiene el textbox</param>
        /// <returns>
        /// Devuelve true si la cantidad de caracteres está dentro del rango deseado y false si no
        /// </returns>
        public bool ValidarCampoTexto(int longMin, int longMax, int longReal)
        {
            if ((longReal > longMax) || (longReal < longMin))
            {
                return false;
            }
            else
            {
                return true;
            }

        }
        #endregion
    }
}